#include "record.h"
#define LOG_SET_LOCAL_LEVEL LOG_LEVEL_NONE
#include "log.h"

void record_init(Record *thiz, uint32_t capacity, char *name) {
    
    assert_param(thiz != NULL);
  
    thiz->TailPtr = thiz->HeadPtr = NULL;
    thiz->Len = 0U;
    thiz->Capacity = capacity;
    thiz->name = name;
}

void record_reset(Record *thiz) {
    
	thiz->HeadPtr = thiz->TailPtr = NULL;
	thiz->Len = 0U;
}

void record_push(Record *thiz, segment_t* segPtr) {
    
    assert_param(thiz != NULL);
    assert_param(segPtr != NULL);
    assert_param(thiz->Len <= thiz->Capacity);

    thiz->HeadPtr = thiz->HeadPtr == NULL ? segPtr : thiz->HeadPtr;
    thiz->TailPtr = segPtr;
    thiz->Len++;
    LOG_debug("Push segment(%d) into record(%s)->Len: %d", segPtr->No, thiz->name, thiz->Len);  
}

segment_t* record_pop_head(Record *thiz) {
    
    assert_param(thiz != NULL);
    assert_param(thiz->HeadPtr != NULL);

    segment_t *headPtr = thiz->HeadPtr;
    thiz->HeadPtr++;
	if(thiz->HeadPtr == thiz->TailPtr + 1U) {
		record_reset(thiz);
	}else {
        thiz->Len--;
    }
    LOG_debug("Pop head segment(%d) from record(%s)->Len: %d", headPtr->No, thiz->name, thiz->Len); 
    return headPtr;
}

segment_t* record_pop_tail(Record *thiz) {
    
    assert_param(thiz != NULL);
    assert_param(thiz->TailPtr != NULL);
	
	segment_t *tailPtr = thiz->TailPtr;
    thiz->TailPtr--;
    if(thiz->TailPtr == thiz->HeadPtr - 1U) {
		record_reset(thiz);
	}else {
        thiz->Len--;
    }
    LOG_debug("Pop head segment(%d) from record(%s)->Len: %d", tailPtr->No, thiz->name, thiz->Len); 
    return tailPtr;
}

void record_move_front(Record *thiz) {
    
    assert_param(thiz != NULL);
    
    mem_pool_move(thiz->HeadPtr + 1U, thiz->HeadPtr, thiz->Len - 1);
    mem_pool_rel(thiz->TailPtr);
	thiz->TailPtr--;
	thiz->Len--;
}
